const { createLogger, format, transports } = require('winston');
const fs = require('fs');
const path = require('path');
const readline = require('readline');

export class Logger {
  constructor() {
    this.logger = null;
    this.logPath = null;
  }

  setLogPath(logPath) {
    // 创建日志目录
    this.logPath = logPath;
    const logDir = path.dirname(logPath);
    if (!fs.existsSync(logDir)) {
      fs.mkdirSync(logDir, { recursive: true });
    }

    this.logger = createLogger({
      level: 'info',
      format: format.combine(
        format.timestamp({
          format: 'YYYY-MM-DD HH:mm:ss'
        }),
        format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
      ),
      transports: [
        new transports.File({ filename: logPath, level: 'info' }),
        new transports.Console()
      ],
      exceptionHandlers: [
        new transports.File({ filename: path.join(logDir, 'exceptions.log') })
      ],
      exitOnError: false
    });
  }

  log(message) {
    if (this.logger) {
      this.logger.info(message);
    } else {
      console.error('Logger has not been initialized');
    }
  }

  error(message) {
    if (this.logger) {
      this.logger.error(message);
    } else {
      console.error('Logger has not been initialized');
    }
  }

  info(message) {
    if (this.logger) {
      this.logger.info(message);
    } else {
      console.error('Logger has not been initialized');
    }
  }

  warn(message) {
    if (this.logger) {
      this.logger.warn(message);
    } else {
      console.error('Logger has not been initialized');
    }
  }


  getLastLines(numLines) {
    let lastLines = [];
    return new Promise((resolve, reject) => {
      const stream = fs.createReadStream(this.logPath, { encoding: 'utf8' });
      const rl = readline.createInterface({
        input: stream,
        crlfDelay: Infinity
      });

      let lines = [];
      rl.on('line', (line) => {
        lines.push(line);
        if (lines.length > numLines) {
          lines.shift();
        }
      }).on('close', () => {
        resolve(lines);
      });
    });
  }
}

